package flexconsole.controls
{
	import flash.display.DisplayObject;
	import flash.utils.*;
	
	import mx.collections.ArrayCollection;
	import mx.collections.IViewCursor;
	import mx.containers.Box;
	import mx.controls.Text;
	import mx.core.Application;
	import mx.core.IFlexDisplayObject;
	import mx.effects.Tween;
	import mx.managers.PopUpManager;
	import mx.styles.CSSStyleDeclaration;
	import mx.styles.StyleManager;

	/**
	 * FeedbackBox is a modal box with a simple notification message for non intrusive notification.
	 * 
	 * <p>It is designed to display messages into information displays using modeless feedback.
	 * Modeless feedback allows you to integrate information into the user's flow without breaking her flow.</p>
	 * 
	 * @author ivanchoo
	 * 
	 */
	public class FeedbackBox extends Box
	{
		/**
		 * @private
		 * Set the default styles.
		 */
		private static function initializeStyles():void {
			var styleDeclaration:CSSStyleDeclaration = StyleManager.getStyleDeclaration("FeedbackBox");
			if(!styleDeclaration) {
				styleDeclaration = new CSSStyleDeclaration();
			}
			styleDeclaration.defaultFactory = function():void {
				this.backgroundAlpha = 0.7;
				this.backgroundColor = 0x000000;
				this.borderColor = 0xFFFFFF;
				this.borderStyle = 'solid';
				this.borderThickness = 2;
				this.color = 0xFFFFFF;
				this.cornerRadius = 12;
				this.paddingBottom = 6;
				this.paddingLeft = 6;
				this.paddingRight = 6;
				this.paddingTop = 6;
				this.fontSize = 18;
				this.dropShadowEnabled = true;
			};
			
			StyleManager.setStyleDeclaration("FeedbackBox", styleDeclaration, false);
		}
		
		initializeStyles();
		
		private static var instances:ArrayCollection;
		
		/**
		 * Shows a Feedback Box with the message.
		 * 
		 * @param message String to display.
		 * 
		 */
		public static function show(message:String):void {
			if (!instances) {
				instances = new ArrayCollection();
			}
			var box:FeedbackBox = new FeedbackBox();
			PopUpManager.addPopUp(box as IFlexDisplayObject, Application.application as DisplayObject, false);
			box.text = message;
			PopUpManager.centerPopUp(box as IFlexDisplayObject);
			box.alpha = 0;
			box.fadeIn();
			instances.addItem(box);
		}
		
		private static function onFadeIn(instance:FeedbackBox):void {
			instance.timeoutID = setTimeout(instance.fadeOut, 1500); 

		}
		
		private static function onFadeOut(instance:FeedbackBox):void {
			if (instance.timeoutID) {
				clearTimeout(instance.timeoutID);
			}
			instances.removeItemAt(instances.getItemIndex(instance));
			PopUpManager.removePopUp(instance);
		}
		
		/**
		 * @private
		 */
		public var feedback_txt:Text;
		private var tween:Tween;
		private var timeoutID:uint;
		
		public function FeedbackBox() {
			super();
			verticalScrollPolicy = "off";
			horizontalScrollPolicy = "off";
		}
		
		/**
		 * The string that is displayed in the FeedbackBox.
		 * 
		 * <p>You shouldn't have to set this directly. Use <code>FeedbackBox.show()</code> instead.</p>
		 * 
		 * @return String
		 * 
		 */
		public function get text():String {
			return feedback_txt.text;
		}
		
		/**
		 * @private
		 */
		public function set text(text:String):void {
			feedback_txt.text = text;
		}

		/**
		 * Causes the FeedbackBox to fade in.
		 * 
		 * <p>You shouldn't have to call this directly. Use <code>FeedbackBox.show()</code> instead.</p>
		 * 
		 */
		public function fadeIn():void {
			if (tween) {
				tween.stop();
			}
			tween = new Tween(this, 0, 100, 500, -1, updateTween, endTween);
		}
		
		/**
		 * Causes the FeedbackBox to fade out.
		 * 
		 * <p>You shouldn't have to call this directly. Use <code>FeedbackBox.show()</code> instead.</p>
		 * 
		 */
		public function fadeOut():void {
			if (tween) {
				tween.stop();
			}
			tween = new Tween(this, 100, 0, 500, -1, updateTween, endTween);
		}

		private function updateTween(val:int):void {
			alpha = val / 100;
		}
		
		private function endTween(val:Object):void {
			tween = null;
			if (alpha) {
				onFadeIn(this);
			} else {
				onFadeOut(this);
			}
		}
		
		/**
		 * @inheritDoc
		 */
		override protected function createChildren():void {
			super.createChildren();
			feedback_txt = new Text;
			addChild(feedback_txt);
		}

		
	}
}